package org.hs.phd.common.geometry;

public class LawOfCosineGeodesicNorm2D implements Norm2D {

	
	//these allow for some dirty optimization, but kill Thread-safety
	private static long lastLat1Bits = -1;
	private static double lastSinLat1 = -1;
	private static double lastCosLat1 = -1;

	protected LawOfCosineGeodesicNorm2D(){
		
	}
	
	@Override
	public double distance(double lon1, double lat1, double lon2, double lat2) {
		
		long latBits = Double.doubleToLongBits(lat1);
		if(lastLat1Bits == latBits){
			return Math.acos(lastSinLat1*Math.sin(lat2) + lastCosLat1*Math.cos(lat2)*Math.cos(lon2 - lon1) );
		}
		lastLat1Bits = latBits;
		
		double sinLat1 = Math.sin(lat1);
		double sinLat2 = Math.sin(lat2);
		double cosLat1 = Math.cos(lat1);
		double cosLat2 = Math.cos(lat2);
		double cosDeltaLon = Math.cos(lon2 - lon1);
		
		lastSinLat1 = sinLat1;
		lastCosLat1 = cosLat1;
		
		return Math.acos(sinLat1*sinLat2 + cosLat1*cosLat2*cosDeltaLon );
	}

}
